package cn.amaake.magicplugin.satoken.web;

import cn.amaake.magicplugin.satoken.config.MagicApiSaTokenConfig;
import cn.amaake.magicplugin.satoken.interfaces.SatokenAbstract;
import cn.amaake.magicplugin.satoken.model.SatokenUser;
import cn.dev33.satoken.oauth2.exception.SaOAuth2Exception;
import cn.dev33.satoken.oauth2.logic.SaOAuth2Util;
import cn.dev33.satoken.oauth2.model.AccessTokenModel;
import cn.dev33.satoken.oauth2.model.ClientTokenModel;
import cn.dev33.satoken.util.SaResult;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.ssssssss.magicapi.core.config.MagicConfiguration;
import org.ssssssss.magicapi.core.exception.MagicLoginException;
import org.ssssssss.magicapi.core.model.ApiInfo;
import org.ssssssss.magicapi.core.model.JsonBean;
import org.ssssssss.magicapi.core.model.Option;
import org.ssssssss.magicapi.core.model.Options;
import org.ssssssss.magicapi.core.service.MagicResourceService;
import org.ssssssss.magicapi.core.servlet.MagicHttpServletRequest;
import org.ssssssss.magicapi.core.web.MagicController;
import org.ssssssss.magicapi.core.web.MagicExceptionHandler;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * satoken公共接口
 */
public class SatokenUtilController extends MagicController implements MagicExceptionHandler {

    private MagicResourceService service = MagicConfiguration.getMagicResourceService();

    private final MagicApiSaTokenConfig magicApiSaTokenConfig;

    private final SatokenAbstract satokenAbstract;

    public SatokenUtilController(MagicApiSaTokenConfig magicApiSaTokenConfig,MagicConfiguration configuration,ApplicationContext applicationContext) {
        super(configuration);
        this.magicApiSaTokenConfig = magicApiSaTokenConfig;
        satokenAbstract = applicationContext.getBean(SatokenAbstract.class);
    }

    @PostMapping("/getRoleAll")
    @ResponseBody
    public List<Option> getRoleAll(MagicHttpServletRequest request){
        List<ApiInfo> apiInfoList = service.files("api");

        apiInfoList = apiInfoList.stream().distinct().collect(Collectors.toList());
        List<Option> optionList = new ArrayList<>();
        for(ApiInfo apiInfo : apiInfoList){
            for(Option option : apiInfo.getOptions()){
                if(option.getName().equals(Options.ROLE.getValue())){
                    optionList.add(option);
                }
            }
        }
        return getOptions(optionList);
    }



    @PostMapping("/getPermissionAll")
    @ResponseBody
    public List<Option> getPermissionAll(MagicHttpServletRequest request){
        List<ApiInfo> apiInfoList = service.files("api");
        apiInfoList = apiInfoList.stream().distinct().collect(Collectors.toList());
        List<Option> optionList = new ArrayList<>();
        for(ApiInfo apiInfo : apiInfoList){
            for(Option option : apiInfo.getOptions()){
                if(option.getName().equals(Options.PERMISSION.getValue())){
                    optionList.add(option);
                }
            }
        }
        return getOptions(optionList);
    }


    @PostMapping("/getSatokenUserbyid")
    @ResponseBody
    public SaResult getSatokenUserbyid(MagicHttpServletRequest request){
        if(magicApiSaTokenConfig.isCheckClient()){
            String clientToken = request.getHeader("client_token");
            try {
                SaOAuth2Util.checkClientToken(clientToken);
            }catch (SaOAuth2Exception e){
                return SaResult.error("clientToken无效");
            }
            try {
                SaOAuth2Util.checkClientTokenScope(clientToken, "oauth2Server");
            }catch (SaOAuth2Exception e){
                return SaResult.error("没有访问oauth2Server的权限");
            }
        }
        String access_token = request.getHeader("access_token");
        AccessTokenModel accessTokenModel = null;
        try{
            accessTokenModel = SaOAuth2Util.checkAccessToken(access_token);
        }catch (SaOAuth2Exception e){
            return SaResult.error("accessToken无效");
        }
        SatokenUser satokenUser = satokenAbstract.getSatokenUserbyid(accessTokenModel.loginId);
        return SaResult.data(satokenUser);
    }

    private List<Option> getOptions(List<Option> optionList) {
        if(!optionList.isEmpty()){
            for(int i = 0;i<optionList.size() - 1;i++){
                for(int j = optionList.size() - 1; j > i; j--){
                    if(optionList.get(j).getValue().equals(optionList.get(i).getValue())){
                        optionList.remove(j);
                    }
                }
            }
        }
        return optionList;
    }
}
